
#include "../Native/trunk_store.h"
#include "SingleVersionStore.h"

using namespace System;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;

namespace O1 {
	namespace Storage {

		SingleVersionStore::SingleVersionStore(Int64 initialCapacity) {
			Memory::get_edge_store()->initialize(initialCapacity);
		};

		SingleVersionStore::~SingleVersionStore() {
			Memory::get_edge_store()->clear();
		};

		Int64 SingleVersionStore::Add(array<Byte>^ value) {
			const int sz = value->Length;
			if (sz < 1)
			{
				return Memory::get_edge_store()->add_cell(static_cast<unsigned char*>(nullptr), 0);
			}

			pin_ptr<unsigned char> array_pin = &value[0];
			auto data = static_cast<Byte*>(array_pin);
			return Memory::get_edge_store()->add_cell(data, sz);
		};

		Int64 SingleVersionStore::Write(Int64 index, array<Byte>^ value) {
			auto sz = value->Length;
			if (sz < 1)
			{
				return Memory::get_edge_store()->write_cell(index, static_cast<unsigned char*>(nullptr), 0);
			}

			pin_ptr<unsigned char> array_pin = &value[0];
			auto data = static_cast<Byte*>(array_pin);
			return Memory::get_edge_store()->write_cell(index, data, sz);
		};

		Int64 SingleVersionStore::Delete(Int64 index) {
			return Memory::get_edge_store()->delete_cell(index);
		}

		array<Byte>^ SingleVersionStore::Read(Int64 index) {
			auto cell = Memory::get_edge_store()->read_cell(index);
			if (cell == nullptr)
			{
				return nullptr;
			}

			if (cell->get_value() == nullptr)
			{
				return gcnew array<Byte>(0);
			}

			auto sz = cell->get_size();
			array<Byte>^ result = gcnew array<Byte>(sz);
			pin_ptr<unsigned char> array_pin = &result[0];
			memcpy(array_pin, cell->get_value(), sz);
			return result;
		};
	};
}